package com.rtx.edi.platform.mapping.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import javax.annotation.Resource;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rtx.edi.model.api.dto.PlApiMappingDTO;
import com.rtx.edi.model.api.dto.PlApiMappingEditDTO;
import com.rtx.edi.model.api.dto.PlApiMappingStructureDTO;
import com.rtx.edi.model.api.po.PlApiMapping;
import com.rtx.edi.model.api.po.PlApiMappingStructure;
import com.rtx.edi.model.apibaseinfo.po.PlApibaseinfo;
import com.rtx.edi.platform.baseinfo.mapper.PlApibaseinfoMapper;
import com.rtx.edi.platform.mapping.mapper.PlApiMappingMapper;
import com.rtx.edi.platform.mapping.service.PlApiMappingService;
import com.rtx.edi.platform.structure.mapper.PlApiMappingStructureMapper;
import com.rtx.edi.platform.synctask.api.GatWayAPI;
import com.rtx.edi.platform.synctask.service.GatWayService;

/**
 * <p>
 * 场景映射
 * </p>
 *
 * @author cafebabe
 * @since 2023-03-10
 */
@Service
public class PlApiMappingServiceImpl extends ServiceImpl<PlApiMappingMapper, PlApiMapping> implements PlApiMappingService {

	@Autowired
	PlApiMappingMapper plApiMappingMapper;
	
	@Autowired
	PlApiMappingStructureMapper plApiMappingStructureMapper;
	
	@Autowired
	PlApibaseinfoMapper apibaseinfoMapper;
	
	@Autowired
	ApplicationContext applicationContext;
	
	@Resource(name = "ApiGatWayService")
	GatWayService gatWayService;
	
	
	
	
	@Override
	public PlApiMapping selectByApiMappingCode(String apiMappingCode) {
		LambdaQueryWrapper<PlApiMapping> query = Wrappers.lambdaQuery();
		query.eq(PlApiMapping::getApiMappingCode, apiMappingCode);
		return baseMapper.selectList(query).get(0);
	}

	@Override
	public List<Map<String, String>> selectPlApiMappingSelect() {
		List<Map<String, String>> list = new ArrayList<Map<String,String>>();
		Map<String, String> s1 = new HashMap<String, String>();
		s1.put("label", "");
		s1.put("value", "");
		list.add(s1);
		for(PlApiMapping m:baseMapper.selectList(Wrappers.lambdaQuery())) {
			Map<String, String> s = new HashMap<String, String>();
			s.put("label", m.getApiMappingName());
			s.put("value", m.getApiMappingCode());
			list.add(s);
		}
		return list;
	}

	
	@Override
	public void selectPlApiMappingList(Page<PlApiMapping> pageParam, PlApiMapping qcd) {
		QueryWrapper<PlApiMapping> query = new QueryWrapper<>();
        query.orderByAsc("id"); 
        if(qcd != null){
            //公司编号、公司名称、公司类型、公司状态
        	if(StringUtils.hasText(qcd.getApplicationLinkName())) {
        		query.like("application_link_name", qcd.getApplicationLinkName());
        	}
        	if(StringUtils.hasText(qcd.getApplicationLinkDtlName())) {
        		query.like("application_link_dtl_name", qcd.getApplicationLinkDtlName());
        	}
        	if(StringUtils.hasText(qcd.getApiMappingName())) {
        		query.like("api_mapping_name", qcd.getApiMappingName());
        	}
        	if(StringUtils.hasText(qcd.getSourceApiName())) {
        		query.like("source_api_name", qcd.getSourceApiName());
        	}
        	if(StringUtils.hasText(qcd.getTargetApiName())) {
        		query.like("target_api_name", qcd.getTargetApiName());
        	}
        	if(StringUtils.hasText(qcd.getApiMappingCode())) {
        		query.like("api_mapping_code", qcd.getApiMappingCode());
        	}
        	if(StringUtils.hasText(qcd.getApiMappingName())) {
        		query.like("api_mapping_name", qcd.getApiMappingName());
        	}
        }
        baseMapper.selectPage(pageParam,query);
	}

	@Override
	public void deletePlApiMappingByIds(List<PlApiMappingDTO> list) {
		for(PlApiMappingDTO dto:list) {
			plApiMappingMapper.updIsdelteFlag(dto.getId());
		}
	}

	@Override
	public void addApiMapping(PlApiMappingDTO dto) {
		checkPlApiMapping(dto);
		
		LambdaQueryWrapper<PlApiMapping> qw = Wrappers.lambdaQuery();
		qw
		.eq(PlApiMapping::getApiMappingCode, dto.getApiMappingCode());
		boolean exists = baseMapper.exists(qw);
		if(exists) {
			throw new RuntimeException("对接场景编码已存在不允许重复创建");
		}
		PlApiMapping po = new PlApiMapping();
		BeanUtils.copyProperties(dto, po);
		save(po);
	}
	
	private void checkPlApiMapping(PlApiMappingDTO dto) {
	       Assert.notNull(dto.getApplicationLinkId(),"关联应用id不能为空");
	       Assert.notNull(dto.getApplicationLinkDtlId(), "关联应用环境id不能为空");
	       Assert.notNull(dto.getSourceApiId(),"源接口id不能为空");
	       Assert.notNull(dto.getTargetApiId(),"目标接口id不能为空");
	       Assert.hasLength(dto.getApplicationLinkName(),"关联应用名称不能为空");
	       Assert.hasLength(dto.getApplicationLinkDtlName(),"关联应用环境名称不能为空");
	       Assert.hasLength(dto.getSourceApiName(),"源接口名称不能为空");
	       Assert.hasLength(dto.getTargetApiName(),"目标接口名称不能为空");
	}

	
	@Override
	public void updApiMapping(PlApiMappingDTO dto) {
		QueryWrapper<PlApiMapping> query = new QueryWrapper<>();
	}

	/**
	 * 	更新&添加PlApiMappingStructure
	 */
	@Override
	public void editPlApiMappingStructure(PlApiMappingEditDTO dto) {
		PlApiMapping po = new PlApiMapping();
		BeanUtils.copyProperties(dto, po);
		
		//假如为sql填充
		if("table".equals(po.getActiveTarget())) {
			String externRequestUrl = "method="+dto.getApiMappingCode();
			PlApibaseinfo sapi = apibaseinfoMapper.selectById(dto.getSourceApiId());
			String externRequestData = sapi.getApiRequestTemplate();
//			po.setExternRequestData(externRequestData);
//			po.setExternRequestUrl(externRequestUrl);
		}
		

		baseMapper.updateById(po);
		
		for(PlApiMappingStructureDTO structureDTO:dto.getDetails()) {
			PlApiMappingStructure structurePO = new PlApiMappingStructure();
			BeanUtils.copyProperties(structureDTO, structurePO);
			structurePO.setCompanyId(dto.getCompanyId());
			
			//节点字段不允许更新
			if(!Arrays.asList("array,object".split(",")).contains(structurePO.getTargetFieldType())) {
				String sourceField = Optional.ofNullable(structureDTO.getSourceField()).orElse("");
				String fieldFullPath = Optional.ofNullable(structureDTO.getFieldFullPath()).orElse("");
				String[] sourceFieldArray = sourceField.split("\\.");
				structurePO.setTargetFieldPath(fieldFullPath.replace("root.", ""));
				structurePO.setSourceFieldPath(sourceField.replace("root.", ""));
				structurePO.setSourceFieldName(sourceFieldArray[sourceFieldArray.length-1]);
			}
			
			
			
			//当为是否为报文字段
			if(!StringUtils.hasLength(structurePO.getIsfiledrequest())) {
				if("table".equals(po.getActiveTarget())) {
					//假如最终为拼接sql插入表，请求字段需要手动设置
					if(Arrays.asList("array,object".split(",")).contains(structurePO.getTargetFieldType())) {
						structurePO.setIsfiledrequest("true");
					}else {
						structurePO.setIsfiledrequest("false");
					}
				}else {
					structurePO.setIsfiledrequest("true");
				}
			}
			
			
			LambdaQueryWrapper<PlApiMappingStructure> qw = Wrappers.lambdaQuery();
			qw.eq(PlApiMappingStructure::getId, structurePO.getId());
			boolean exists = plApiMappingStructureMapper.exists(qw);
			if(exists) {
				plApiMappingStructureMapper.updateById(structurePO);
			}else {
				plApiMappingStructureMapper.insert(structurePO);
			}
			
			
		}
	}

	@Override
	public String sendTestRequest(String data) {
		JSONObject requestData = JSON.parseObject(data);
		Long id = Long.parseLong(requestData.getString("id")); 
		String request = requestData.getString("request"); 
		PlApiMapping plApiMapping =	baseMapper.selectById(id);
		
		GatWayAPI gatWayAPI = null;
		if(StringUtils.hasLength(plApiMapping.getActivegatway())) {
			gatWayAPI = (GatWayAPI) applicationContext.getBean(plApiMapping.getActivegatway());
		}else {
			gatWayAPI = gatWayService;
		}
		return gatWayAPI.handel(plApiMapping.getApiMappingCode(),request);
	}
}
